
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>传输和协议 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="策略" href="asyncio-policy.html" />
    <link rel="prev" title="Futures" href="asyncio-future.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/library/asyncio-protocol.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="asyncio-policy.html" title="策略"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="asyncio-future.html" title="Futures"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="asyncio.html" accesskey="U"><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="transports-and-protocols">
<span id="asyncio-transports-protocols"></span><h1>传输和协议<a class="headerlink" href="#transports-and-protocols" title="永久链接至标题">¶</a></h1>
<p class="rubric">前言</p>
<p>传输和协议会被像 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> 这类 <strong>底层</strong> 事件循环接口使用。它们使用基于回调的编程风格支持网络或IPC协议（如HTTP）的高性能实现。</p>
<p>基本上，传输和协议应只在库和框架上使用，而不应该在高层的异步应用中使用它们。</p>
<p>本文档包含  <a class="reference internal" href="#transports">Transports</a> 和 <a class="reference internal" href="#protocols">Protocols</a> 。</p>
<p class="rubric">概述</p>
<p>在最顶层，传输只关心 <strong>怎样</strong> 传送字节内容，而协议决定传送 <strong>哪些</strong> 字节内容(还要在一定程度上考虑何时)。</p>
<p>也可以这样说：从传输的角度来看，传输是套接字(或类似的I/O终端)的抽象，而协议是应用程序的抽象。</p>
<p>换另一种说法，传输和协议一起定义网络I/0和进程间I/O的抽象接口。</p>
<p>传输对象和协议对象总是一对一关系：协议调用传输方法来发送数据，而传输在接收到数据时调用协议方法传递数据。</p>
<p>大部分面向连接的事件循环方法(如 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> ) 通常接受  <em>protocol_factory</em> 参数为接收到的链接创建 <em>协议</em> 对象，并用 <em>传输</em> 对象来表示。这些方法一般会返回 <code class="docutils literal notranslate"><span class="pre">(transport,</span> <span class="pre">protocol)</span></code> 元组。</p>
<p class="rubric">目录</p>
<p>本文档包含下列小节:</p>
<ul class="simple">
<li><p><a class="reference internal" href="#transports">传输</a> 部分记载异步IO <a class="reference internal" href="#asyncio.BaseTransport" title="asyncio.BaseTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseTransport</span></code></a> 、 <a class="reference internal" href="#asyncio.ReadTransport" title="asyncio.ReadTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">ReadTransport</span></code></a> 、 <a class="reference internal" href="#asyncio.WriteTransport" title="asyncio.WriteTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">WriteTransport</span></code></a> 、 <a class="reference internal" href="#asyncio.Transport" title="asyncio.Transport"><code class="xref py py-class docutils literal notranslate"><span class="pre">Transport</span></code></a> 、 <a class="reference internal" href="#asyncio.DatagramTransport" title="asyncio.DatagramTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">DatagramTransport</span></code></a> 和 <a class="reference internal" href="#asyncio.SubprocessTransport" title="asyncio.SubprocessTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">SubprocessTransport</span></code></a> 等类。</p></li>
<li><p>The <a class="reference internal" href="#protocols">Protocols</a> section documents asyncio <a class="reference internal" href="#asyncio.BaseProtocol" title="asyncio.BaseProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseProtocol</span></code></a>,
<a class="reference internal" href="#asyncio.Protocol" title="asyncio.Protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">Protocol</span></code></a>, <a class="reference internal" href="#asyncio.BufferedProtocol" title="asyncio.BufferedProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BufferedProtocol</span></code></a>,
<a class="reference internal" href="#asyncio.DatagramProtocol" title="asyncio.DatagramProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">DatagramProtocol</span></code></a>, and <a class="reference internal" href="#asyncio.SubprocessProtocol" title="asyncio.SubprocessProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">SubprocessProtocol</span></code></a> classes.</p></li>
<li><p><a class="reference internal" href="#examples">例子</a> 部分展示怎样使用传输、协议和底层事件循环接口。</p></li>
</ul>
<div class="section" id="transports">
<span id="asyncio-transport"></span><h2>传输<a class="headerlink" href="#transports" title="永久链接至标题">¶</a></h2>
<p>传输属于 <a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a> 模块中的类，用来抽象各种通信通道。</p>
<p>传输对象总是由 <a class="reference internal" href="asyncio-eventloop.html#asyncio-event-loop"><span class="std std-ref">异步IO事件循环</span></a> 实例化。</p>
<p>异步IO实现TCP、UDP、SSL和子进程管道的传输。传输上可用的方法由传输的类型决定。</p>
<p>传输类属于 <a class="reference internal" href="asyncio-dev.html#asyncio-multithreading"><span class="std std-ref">线程不安全</span></a> 。</p>
<div class="section" id="transports-hierarchy">
<h3>传输层级<a class="headerlink" href="#transports-hierarchy" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="asyncio.BaseTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BaseTransport</code><a class="headerlink" href="#asyncio.BaseTransport" title="永久链接至目标">¶</a></dt>
<dd><p>所有传输的基类。包含所有异步IO传输共用的方法。</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.WriteTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">WriteTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport" title="永久链接至目标">¶</a></dt>
<dd><p>只写链接的基础传输。</p>
<p>Instances of the <em>WriteTransport</em> class are returned from
the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_write_pipe" title="asyncio.loop.connect_write_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_write_pipe()</span></code></a> event loop method and
are also used by subprocess-related methods like
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a>.</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.ReadTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">ReadTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport" title="永久链接至目标">¶</a></dt>
<dd><p>只读链接的基础传输。</p>
<p>Instances of the <em>ReadTransport</em> class are returned from
the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_read_pipe" title="asyncio.loop.connect_read_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_read_pipe()</span></code></a> event loop method and
are also used by subprocess-related methods like
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a>.</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.Transport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">Transport</code><span class="sig-paren">(</span><em class="sig-param">WriteTransport</em>, <em class="sig-param">ReadTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Transport" title="永久链接至目标">¶</a></dt>
<dd><p>接口代表一个双向传输，如TCP链接。</p>
<p>用户不用直接实例化传输；调用一个功能函数，给它传递协议工厂和其它需要的信息就可以创建传输和协议。</p>
<p><em>传输</em> 类实例由如  <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> 、 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_connection" title="asyncio.loop.create_unix_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_connection()</span></code></a> 、  <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a> 、  <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.sendfile" title="asyncio.loop.sendfile"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.sendfile()</span></code></a> 等这类事件循环方法使用或返回。</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.DatagramTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">DatagramTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport" title="永久链接至目标">¶</a></dt>
<dd><p>数据报(UDP)传输链接。</p>
<p><em>DatagramTransport</em> 类实例由事件循环方法 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> 返回。</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.SubprocessTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">SubprocessTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport" title="永久链接至目标">¶</a></dt>
<dd><p>表示父进程和子进程之间连接的抽象。</p>
<p><em>SubprocessTransport</em> 类的实例由事件循环方法 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_shell" title="asyncio.loop.subprocess_shell"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_shell()</span></code></a>  和  <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a> 返回。</p>
</dd></dl>

</div>
<div class="section" id="base-transport">
<h3>基础传输<a class="headerlink" href="#base-transport" title="永久链接至标题">¶</a></h3>
<dl class="method">
<dt id="asyncio.BaseTransport.close">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.close" title="永久链接至目标">¶</a></dt>
<dd><p>关闭传输。</p>
<p>如果传输具有发送数据缓冲区，将会异步发送已缓存的数据。在所有已缓存的数据都已处理后，就会将 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 作为协议 <a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a> 方法的参数并进行调用。在这之后，传输不再接收任何数据。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseTransport.is_closing">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">is_closing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.is_closing" title="永久链接至目标">¶</a></dt>
<dd><p>返回 <code class="docutils literal notranslate"><span class="pre">True</span></code> ，如果传输正在关闭或已经关闭。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseTransport.get_extra_info">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">get_extra_info</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.get_extra_info" title="永久链接至目标">¶</a></dt>
<dd><p>返回 传输或它使用的相关资源信息。</p>
<p><em>name</em> 是表示要获取传输特定信息的字符串。</p>
<p><em>default</em> 是在信息不可用或传输不支持第三方事件循环实现或当前平台查询时返回的值。</p>
<p>例如下面代码尝试获取传输相关套接字对象:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">sock</span> <span class="o">=</span> <span class="n">transport</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s1">&#39;socket&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sock</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">sock</span><span class="o">.</span><span class="n">getsockopt</span><span class="p">(</span><span class="o">...</span><span class="p">))</span>
</pre></div>
</div>
<p>传输可查询信息类别:</p>
<ul class="simple">
<li><p>套接字:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'peername'</span></code>: 套接字链接时的远端地址，<a class="reference internal" href="socket.html#socket.socket.getpeername" title="socket.socket.getpeername"><code class="xref py py-meth docutils literal notranslate"><span class="pre">socket.socket.getpeername()</span></code></a> 方法的结果 (出错时为 <code class="docutils literal notranslate"><span class="pre">None</span></code> )</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'socket'</span></code>: <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 实例</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'sockname'</span></code>: 套接字本地地址， <a class="reference internal" href="socket.html#socket.socket.getsockname" title="socket.socket.getsockname"><code class="xref py py-meth docutils literal notranslate"><span class="pre">socket.socket.getsockname()</span></code></a> 方法的结果</p></li>
</ul>
</li>
<li><p>SSL套接字</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'compression'</span></code>: 用字符串指定压缩算法，或者链接没有压缩时为 <code class="docutils literal notranslate"><span class="pre">None</span></code>  ；<a class="reference internal" href="ssl.html#ssl.SSLSocket.compression" title="ssl.SSLSocket.compression"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.compression()</span></code></a> 的结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'cipher'</span></code>: 一个三值的元组，包含使用密码的名称，定义使用的SSL协议的版本，使用的加密位数。  <a class="reference internal" href="ssl.html#ssl.SSLSocket.cipher" title="ssl.SSLSocket.cipher"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.cipher()</span></code></a> 的结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'peercert'</span></code>: 远端凭证；  <a class="reference internal" href="ssl.html#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.getpeercert()</span></code></a> 结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'sslcontext'</span></code>: <a class="reference internal" href="ssl.html#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code></a> 实例</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'ssl_object'</span></code>: <a class="reference internal" href="ssl.html#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLObject</span></code></a> 或 <a class="reference internal" href="ssl.html#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a> 实例</p></li>
</ul>
</li>
<li><p>管道：</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'pipe'</span></code>: 管道对象</p></li>
</ul>
</li>
<li><p>子进程：</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'subprocess'</span></code>: <a class="reference internal" href="subprocess.html#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal notranslate"><span class="pre">subprocess.Popen</span></code></a> 实例</p></li>
</ul>
</li>
</ul>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseTransport.set_protocol">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">set_protocol</code><span class="sig-paren">(</span><em class="sig-param">protocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.set_protocol" title="永久链接至目标">¶</a></dt>
<dd><p>设置一个新协议。</p>
<p>只有两种协议都写明支持切换才能完成切换协议。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseTransport.get_protocol">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">get_protocol</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.get_protocol" title="永久链接至目标">¶</a></dt>
<dd><p>返回当前协议。</p>
</dd></dl>

</div>
<div class="section" id="read-only-transports">
<h3>只读传输<a class="headerlink" href="#read-only-transports" title="永久链接至标题">¶</a></h3>
<dl class="method">
<dt id="asyncio.ReadTransport.is_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">is_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.is_reading" title="永久链接至目标">¶</a></dt>
<dd><p>如果传输接收到新数据时返回 <code class="docutils literal notranslate"><span class="pre">True</span></code> 。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能.</span></p>
</div>
</dd></dl>

<dl class="method">
<dt id="asyncio.ReadTransport.pause_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">pause_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.pause_reading" title="永久链接至目标">¶</a></dt>
<dd><p>暂停传输的接收端。<a class="reference internal" href="#asyncio.Protocol.data_received" title="asyncio.Protocol.data_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.data_received()</span></code></a> 方法将不会收到数据，除非 <a class="reference internal" href="#asyncio.ReadTransport.resume_reading" title="asyncio.ReadTransport.resume_reading"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_reading()</span></code></a>  被调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>这个方法幂等的， 它可以在传输已经暂停或关闭时调用。</p>
</div>
</dd></dl>

<dl class="method">
<dt id="asyncio.ReadTransport.resume_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">resume_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.resume_reading" title="永久链接至目标">¶</a></dt>
<dd><p>恢复接收端。如果有数据可读取时，协议方法 <a class="reference internal" href="#asyncio.Protocol.data_received" title="asyncio.Protocol.data_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.data_received()</span></code></a> 将再次被调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>这个方法幂等的， 它可以在传输已经准备好读取数据时调用。</p>
</div>
</dd></dl>

</div>
<div class="section" id="write-only-transports">
<h3>只写传输<a class="headerlink" href="#write-only-transports" title="永久链接至标题">¶</a></h3>
<dl class="method">
<dt id="asyncio.WriteTransport.abort">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.abort" title="永久链接至目标">¶</a></dt>
<dd><p>立即关闭传输，不会等待已提交的操作处理完毕。已缓存的数据将会丢失。不会接收更多数据。   最终 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 将作为协议的 <a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a>  方法的参数被调用。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.can_write_eof">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">can_write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.can_write_eof" title="永久链接至目标">¶</a></dt>
<dd><p>如果传输支持 <a class="reference internal" href="#asyncio.WriteTransport.write_eof" title="asyncio.WriteTransport.write_eof"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write_eof()</span></code></a> 返回  <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a> 否则返回  <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>  。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.get_write_buffer_size">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">get_write_buffer_size</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.get_write_buffer_size" title="永久链接至目标">¶</a></dt>
<dd><p>返回传输使用输出缓冲区的当前大小。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.get_write_buffer_limits">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">get_write_buffer_limits</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.get_write_buffer_limits" title="永久链接至目标">¶</a></dt>
<dd><p>获取写入流控制 <em>high</em> 和 <em>low</em> 高低标记位。返回元组 <code class="docutils literal notranslate"><span class="pre">(low,</span> <span class="pre">high)</span></code> ， <em>low</em> 和 <em>high</em> 为正字节数。</p>
<p>使用 <a class="reference internal" href="#asyncio.WriteTransport.set_write_buffer_limits" title="asyncio.WriteTransport.set_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_write_buffer_limits()</span></code></a> 设置限制。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4.2 新版功能.</span></p>
</div>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.set_write_buffer_limits">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">set_write_buffer_limits</code><span class="sig-paren">(</span><em class="sig-param">high=None</em>, <em class="sig-param">low=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.set_write_buffer_limits" title="永久链接至目标">¶</a></dt>
<dd><p>设置写入流控制 <em>high</em> 和 <em>low</em> 高低标记位。</p>
<p>These two values (measured in number of
bytes) control when the protocol's
<a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.pause_writing()</span></code></a>
and <a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.resume_writing()</span></code></a>
methods are called. If specified, the low watermark must be less
than or equal to the high watermark.  Neither <em>high</em> nor <em>low</em>
can be negative.</p>
<p><a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> is called when the buffer size
becomes greater than or equal to the <em>high</em> value. If writing has
been paused, <a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> is called when
the buffer size becomes less than or equal to the <em>low</em> value.</p>
<p>The defaults are implementation-specific.  If only the
high watermark is given, the low watermark defaults to an
implementation-specific value less than or equal to the
high watermark.  Setting <em>high</em> to zero forces <em>low</em> to zero as
well, and causes <a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> to be called
whenever the buffer becomes non-empty.  Setting <em>low</em> to zero causes
<a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> to be called only once the
buffer is empty. Use of zero for either limit is generally
sub-optimal as it reduces opportunities for doing I/O and
computation concurrently.</p>
<p>Use <a class="reference internal" href="#asyncio.WriteTransport.get_write_buffer_limits" title="asyncio.WriteTransport.get_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_write_buffer_limits()</span></code></a>
to get the limits.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.write">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.write" title="永久链接至目标">¶</a></dt>
<dd><p>Write some <em>data</em> bytes to the transport.</p>
<p>This method does not block; it buffers the data and arranges for it
to be sent out asynchronously.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.writelines">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">writelines</code><span class="sig-paren">(</span><em class="sig-param">list_of_data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.writelines" title="永久链接至目标">¶</a></dt>
<dd><p>Write a list (or any iterable) of data bytes to the transport.
This is functionally equivalent to calling <a class="reference internal" href="#asyncio.WriteTransport.write" title="asyncio.WriteTransport.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a> on each
element yielded by the iterable, but may be implemented more
efficiently.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.WriteTransport.write_eof">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.write_eof" title="永久链接至目标">¶</a></dt>
<dd><p>Close the write end of the transport after flushing all buffered data.
Data may still be received.</p>
<p>This method can raise <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a> if the transport
(e.g. SSL) doesn't support half-closed connections.</p>
</dd></dl>

</div>
<div class="section" id="datagram-transports">
<h3>数据报传输<a class="headerlink" href="#datagram-transports" title="永久链接至标题">¶</a></h3>
<dl class="method">
<dt id="asyncio.DatagramTransport.sendto">
<code class="sig-prename descclassname">DatagramTransport.</code><code class="sig-name descname">sendto</code><span class="sig-paren">(</span><em class="sig-param">data</em>, <em class="sig-param">addr=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport.sendto" title="永久链接至目标">¶</a></dt>
<dd><p>Send the <em>data</em> bytes to the remote peer given by <em>addr</em> (a
transport-dependent target address).  If <em>addr</em> is <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>,
the data is sent to the target address given on transport
creation.</p>
<p>This method does not block; it buffers the data and arranges
for it to be sent out asynchronously.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.DatagramTransport.abort">
<code class="sig-prename descclassname">DatagramTransport.</code><code class="sig-name descname">abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport.abort" title="永久链接至目标">¶</a></dt>
<dd><p>Close the transport immediately, without waiting for pending
operations to complete.  Buffered data will be lost.
No more data will be received.  The protocol's
<a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a>
method will eventually be called with <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> as its argument.</p>
</dd></dl>

</div>
<div class="section" id="subprocess-transports">
<span id="asyncio-subprocess-transports"></span><h3>子进程传输<a class="headerlink" href="#subprocess-transports" title="永久链接至标题">¶</a></h3>
<dl class="method">
<dt id="asyncio.SubprocessTransport.get_pid">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_pid</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_pid" title="永久链接至目标">¶</a></dt>
<dd><p>Return the subprocess process id as an integer.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.get_pipe_transport">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_pipe_transport</code><span class="sig-paren">(</span><em class="sig-param">fd</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_pipe_transport" title="永久链接至目标">¶</a></dt>
<dd><p>Return the transport for the communication pipe corresponding to the
integer file descriptor <em>fd</em>:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">0</span></code>: readable streaming transport of the standard input (<em>stdin</em>),
or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> if the subprocess was not created with <code class="docutils literal notranslate"><span class="pre">stdin=PIPE</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">1</span></code>: writable streaming transport of the standard output (<em>stdout</em>),
or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> if the subprocess was not created with <code class="docutils literal notranslate"><span class="pre">stdout=PIPE</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">2</span></code>: writable streaming transport of the standard error (<em>stderr</em>),
or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> if the subprocess was not created with <code class="docutils literal notranslate"><span class="pre">stderr=PIPE</span></code></p></li>
<li><p>other <em>fd</em>: <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a></p></li>
</ul>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.get_returncode">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_returncode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_returncode" title="永久链接至目标">¶</a></dt>
<dd><p>Return the subprocess return code as an integer or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>
if it hasn't returned, which is similar to the
<a class="reference internal" href="subprocess.html#subprocess.Popen.returncode" title="subprocess.Popen.returncode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">subprocess.Popen.returncode</span></code></a> attribute.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.kill">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">kill</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.kill" title="永久链接至目标">¶</a></dt>
<dd><p>杀死子进程。</p>
<p>On POSIX systems, the function sends SIGKILL to the subprocess.
On Windows, this method is an alias for <a class="reference internal" href="#asyncio.SubprocessTransport.terminate" title="asyncio.SubprocessTransport.terminate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">terminate()</span></code></a>.</p>
<p>See also <a class="reference internal" href="subprocess.html#subprocess.Popen.kill" title="subprocess.Popen.kill"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.kill()</span></code></a>.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.send_signal">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">send_signal</code><span class="sig-paren">(</span><em class="sig-param">signal</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.send_signal" title="永久链接至目标">¶</a></dt>
<dd><p>Send the <em>signal</em> number to the subprocess, as in
<a class="reference internal" href="subprocess.html#subprocess.Popen.send_signal" title="subprocess.Popen.send_signal"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.send_signal()</span></code></a>.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.terminate">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">terminate</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.terminate" title="永久链接至目标">¶</a></dt>
<dd><p>停止子进程。</p>
<p>On POSIX systems, this method sends SIGTERM to the subprocess.
On Windows, the Windows API function TerminateProcess() is called to
stop the subprocess.</p>
<p>See also <a class="reference internal" href="subprocess.html#subprocess.Popen.terminate" title="subprocess.Popen.terminate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.terminate()</span></code></a>.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessTransport.close">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.close" title="永久链接至目标">¶</a></dt>
<dd><p>Kill the subprocess by calling the <a class="reference internal" href="#asyncio.SubprocessTransport.kill" title="asyncio.SubprocessTransport.kill"><code class="xref py py-meth docutils literal notranslate"><span class="pre">kill()</span></code></a> method.</p>
<p>If the subprocess hasn't returned yet, and close transports of
<em>stdin</em>, <em>stdout</em>, and <em>stderr</em> pipes.</p>
</dd></dl>

</div>
</div>
<div class="section" id="protocols">
<span id="asyncio-protocol"></span><h2>协议<a class="headerlink" href="#protocols" title="永久链接至标题">¶</a></h2>
<p>asyncio provides a set of abstract base classes that should be used
to implement network protocols.  Those classes are meant to be used
together with <a class="reference internal" href="#asyncio-transport"><span class="std std-ref">transports</span></a>.</p>
<p>Subclasses of abstract base protocol classes may implement some or
all methods.  All these methods are callbacks: they are called by
transports on certain events, for example when some data is received.
A base protocol method should be called by the corresponding transport.</p>
<div class="section" id="base-protocols">
<h3>基础协议<a class="headerlink" href="#base-protocols" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="asyncio.BaseProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BaseProtocol</code><a class="headerlink" href="#asyncio.BaseProtocol" title="永久链接至目标">¶</a></dt>
<dd><p>Base protocol with methods that all protocols share.</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.Protocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">Protocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol" title="永久链接至目标">¶</a></dt>
<dd><p>The base class for implementing streaming protocols
(TCP, Unix sockets, etc).</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.BufferedProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BufferedProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol" title="永久链接至目标">¶</a></dt>
<dd><p>A base class for implementing streaming protocols with manual
control of the receive buffer.</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.DatagramProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">DatagramProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol" title="永久链接至目标">¶</a></dt>
<dd><p>The base class for implementing datagram (UDP) protocols.</p>
</dd></dl>

<dl class="class">
<dt id="asyncio.SubprocessProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">SubprocessProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol" title="永久链接至目标">¶</a></dt>
<dd><p>The base class for implementing protocols communicating with child
processes (unidirectional pipes).</p>
</dd></dl>

</div>
<div class="section" id="base-protocol">
<h3>基础协议<a class="headerlink" href="#base-protocol" title="永久链接至标题">¶</a></h3>
<p>All asyncio protocols can implement Base Protocol callbacks.</p>
<p class="rubric">链接回调函数</p>
<p>Connection callbacks are called on all protocols, exactly once per
a successful connection.  All other protocol callbacks can only be
called between those two methods.</p>
<dl class="method">
<dt id="asyncio.BaseProtocol.connection_made">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">connection_made</code><span class="sig-paren">(</span><em class="sig-param">transport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.connection_made" title="永久链接至目标">¶</a></dt>
<dd><p>链接建立时被调用。</p>
<p>The <em>transport</em> argument is the transport representing the
connection.  The protocol is responsible for storing the reference
to its transport.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseProtocol.connection_lost">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">connection_lost</code><span class="sig-paren">(</span><em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.connection_lost" title="永久链接至目标">¶</a></dt>
<dd><p>链接丢失或关闭时被调用。</p>
<p>The argument is either an exception object or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>.
The latter means a regular EOF is received, or the connection was
aborted or closed by this side of the connection.</p>
</dd></dl>

<p class="rubric">流控制回调函数</p>
<p>Flow control callbacks can be called by transports to pause or
resume writing performed by the protocol.</p>
<p>See the documentation of the <a class="reference internal" href="#asyncio.WriteTransport.set_write_buffer_limits" title="asyncio.WriteTransport.set_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_write_buffer_limits()</span></code></a>
method for more details.</p>
<dl class="method">
<dt id="asyncio.BaseProtocol.pause_writing">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">pause_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.pause_writing" title="永久链接至目标">¶</a></dt>
<dd><p>Called when the transport's buffer goes over the high watermark.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BaseProtocol.resume_writing">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">resume_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.resume_writing" title="永久链接至目标">¶</a></dt>
<dd><p>Called when the transport's buffer drains below the low watermark.</p>
</dd></dl>

<p>If the buffer size equals the high watermark,
<a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> is not called: the buffer size must
go strictly over.</p>
<p>Conversely, <a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> is called when the
buffer size is equal or lower than the low watermark.  These end
conditions are important to ensure that things go as expected when
either mark is zero.</p>
</div>
<div class="section" id="streaming-protocols">
<h3>流协议<a class="headerlink" href="#streaming-protocols" title="永久链接至标题">¶</a></h3>
<p>Event methods, such as <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a>,
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_server" title="asyncio.loop.create_unix_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_server()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a>,
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_connection" title="asyncio.loop.create_unix_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_connection()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_accepted_socket" title="asyncio.loop.connect_accepted_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_accepted_socket()</span></code></a>,
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_read_pipe" title="asyncio.loop.connect_read_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_read_pipe()</span></code></a>, and <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_write_pipe" title="asyncio.loop.connect_write_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_write_pipe()</span></code></a>
accept factories that return streaming protocols.</p>
<dl class="method">
<dt id="asyncio.Protocol.data_received">
<code class="sig-prename descclassname">Protocol.</code><code class="sig-name descname">data_received</code><span class="sig-paren">(</span><em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol.data_received" title="永久链接至目标">¶</a></dt>
<dd><p>Called when some data is received.  <em>data</em> is a non-empty bytes
object containing the incoming data.</p>
<p>Whether the data is buffered, chunked or reassembled depends on
the transport.  In general, you shouldn't rely on specific semantics
and instead make your parsing generic and flexible. However,
data is always received in the correct order.</p>
<p>The method can be called an arbitrary number of times while
a connection is open.</p>
<p>However, <a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a>
is called at most once.  Once <cite>eof_received()</cite> is called,
<code class="docutils literal notranslate"><span class="pre">data_received()</span></code> is not called anymore.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Protocol.eof_received">
<code class="sig-prename descclassname">Protocol.</code><code class="sig-name descname">eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol.eof_received" title="永久链接至目标">¶</a></dt>
<dd><p>Called when the other end signals it won't send any more data
(for example by calling <a class="reference internal" href="#asyncio.WriteTransport.write_eof" title="asyncio.WriteTransport.write_eof"><code class="xref py py-meth docutils literal notranslate"><span class="pre">transport.write_eof()</span></code></a>, if the other end also uses
asyncio).</p>
<p>This method may return a false value (including <code class="docutils literal notranslate"><span class="pre">None</span></code>), in which case
the transport will close itself.  Conversely, if this method returns a
true value, the protocol used determines whether to close the transport.
Since the default implementation returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, it implicitly closes the
connection.</p>
<p>Some transports, including SSL, don't support half-closed connections,
in which case returning true from this method will result in the connection
being closed.</p>
</dd></dl>

<p>状态机：</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>start -&gt; connection_made
    [-&gt; data_received]*
    [-&gt; eof_received]?
-&gt; connection_lost -&gt; end
</pre></div>
</div>
</div>
<div class="section" id="buffered-streaming-protocols">
<h3>缓冲流协议<a class="headerlink" href="#buffered-streaming-protocols" title="永久链接至标题">¶</a></h3>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能: </span><strong>Important:</strong> this has been added to asyncio in Python 3.7
<em>on a provisional basis</em>!  This is as an experimental API that
might be changed or removed completely in Python 3.8.</p>
</div>
<p>Buffered Protocols can be used with any event loop method
that supports <a class="reference internal" href="#streaming-protocols">Streaming Protocols</a>.</p>
<p><code class="docutils literal notranslate"><span class="pre">BufferedProtocol</span></code> implementations allow explicit manual allocation
and control of the receive buffer.  Event loops can then use the buffer
provided by the protocol to avoid unnecessary data copies.  This
can result in noticeable performance improvement for protocols that
receive big amounts of data.  Sophisticated protocol implementations
can significantly reduce the number of buffer allocations.</p>
<p>The following callbacks are called on <a class="reference internal" href="#asyncio.BufferedProtocol" title="asyncio.BufferedProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BufferedProtocol</span></code></a>
instances:</p>
<dl class="method">
<dt id="asyncio.BufferedProtocol.get_buffer">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">get_buffer</code><span class="sig-paren">(</span><em class="sig-param">sizehint</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.get_buffer" title="永久链接至目标">¶</a></dt>
<dd><p>调用后会分配新的接收缓冲区。</p>
<p><em>sizehint</em> is the recommended minimum size for the returned
buffer.  It is acceptable to return smaller or larger buffers
than what <em>sizehint</em> suggests.  When set to -1, the buffer size
can be arbitrary. It is an error to return a buffer with a zero size.</p>
<p><code class="docutils literal notranslate"><span class="pre">get_buffer()</span></code> must return an object implementing the
<a class="reference internal" href="../c-api/buffer.html#bufferobjects"><span class="std std-ref">buffer protocol</span></a>.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BufferedProtocol.buffer_updated">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">buffer_updated</code><span class="sig-paren">(</span><em class="sig-param">nbytes</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.buffer_updated" title="永久链接至目标">¶</a></dt>
<dd><p>用接收的数据更新缓冲区时被调用。</p>
<p><em>nbytes</em> is the total number of bytes that were written to the buffer.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.BufferedProtocol.eof_received">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.eof_received" title="永久链接至目标">¶</a></dt>
<dd><p>See the documentation of the <a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a> method.</p>
</dd></dl>

<p><a class="reference internal" href="#asyncio.BufferedProtocol.get_buffer" title="asyncio.BufferedProtocol.get_buffer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_buffer()</span></code></a> can be called an arbitrary number
of times during a connection.  However, <a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a> is called at most once
and, if called, <a class="reference internal" href="#asyncio.BufferedProtocol.get_buffer" title="asyncio.BufferedProtocol.get_buffer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_buffer()</span></code></a> and
<a class="reference internal" href="#asyncio.BufferedProtocol.buffer_updated" title="asyncio.BufferedProtocol.buffer_updated"><code class="xref py py-meth docutils literal notranslate"><span class="pre">buffer_updated()</span></code></a> won't be called after it.</p>
<p>状态机：</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>start -&gt; connection_made
    [-&gt; get_buffer
        [-&gt; buffer_updated]?
    ]*
    [-&gt; eof_received]?
-&gt; connection_lost -&gt; end
</pre></div>
</div>
</div>
<div class="section" id="datagram-protocols">
<h3>数据报协议<a class="headerlink" href="#datagram-protocols" title="永久链接至标题">¶</a></h3>
<p>Datagram Protocol instances should be constructed by protocol
factories passed to the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> method.</p>
<dl class="method">
<dt id="asyncio.DatagramProtocol.datagram_received">
<code class="sig-prename descclassname">DatagramProtocol.</code><code class="sig-name descname">datagram_received</code><span class="sig-paren">(</span><em class="sig-param">data</em>, <em class="sig-param">addr</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol.datagram_received" title="永久链接至目标">¶</a></dt>
<dd><p>Called when a datagram is received.  <em>data</em> is a bytes object containing
the incoming data.  <em>addr</em> is the address of the peer sending the data;
the exact format depends on the transport.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.DatagramProtocol.error_received">
<code class="sig-prename descclassname">DatagramProtocol.</code><code class="sig-name descname">error_received</code><span class="sig-paren">(</span><em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol.error_received" title="永久链接至目标">¶</a></dt>
<dd><p>Called when a previous send or receive operation raises an
<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a>.  <em>exc</em> is the <a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a> instance.</p>
<p>This method is called in rare conditions, when the transport (e.g. UDP)
detects that a datagram could not be delivered to its recipient.
In many conditions though, undeliverable datagrams will be silently
dropped.</p>
</dd></dl>

<div class="admonition note">
<p class="admonition-title">注解</p>
<p>On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
for datagram protocols, because there is no reliable way to detect send
failures caused by writing too many packets.</p>
<p>The socket always appears 'ready' and excess packets are dropped. An
<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a> with <code class="docutils literal notranslate"><span class="pre">errno</span></code> set to <a class="reference internal" href="errno.html#errno.ENOBUFS" title="errno.ENOBUFS"><code class="xref py py-const docutils literal notranslate"><span class="pre">errno.ENOBUFS</span></code></a> may
or may not be raised; if it is raised, it will be reported to
<a class="reference internal" href="#asyncio.DatagramProtocol.error_received" title="asyncio.DatagramProtocol.error_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">DatagramProtocol.error_received()</span></code></a> but otherwise ignored.</p>
</div>
</div>
<div class="section" id="subprocess-protocols">
<span id="asyncio-subprocess-protocols"></span><h3>子进程协议<a class="headerlink" href="#subprocess-protocols" title="永久链接至标题">¶</a></h3>
<p>Datagram Protocol instances should be constructed by protocol
factories passed to the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a> and
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_shell" title="asyncio.loop.subprocess_shell"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_shell()</span></code></a> methods.</p>
<dl class="method">
<dt id="asyncio.SubprocessProtocol.pipe_data_received">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">pipe_data_received</code><span class="sig-paren">(</span><em class="sig-param">fd</em>, <em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.pipe_data_received" title="永久链接至目标">¶</a></dt>
<dd><p>Called when the child process writes data into its stdout or stderr
pipe.</p>
<p><em>fd</em> is the integer file descriptor of the pipe.</p>
<p><em>data</em> is a non-empty bytes object containing the received data.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessProtocol.pipe_connection_lost">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">pipe_connection_lost</code><span class="sig-paren">(</span><em class="sig-param">fd</em>, <em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.pipe_connection_lost" title="永久链接至目标">¶</a></dt>
<dd><p>与子进程通信的其中一个管道关闭时被调用。</p>
<p><em>fd</em> is the integer file descriptor that was closed.</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.SubprocessProtocol.process_exited">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">process_exited</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.process_exited" title="永久链接至目标">¶</a></dt>
<dd><p>子进程退出时被调用。</p>
</dd></dl>

</div>
</div>
<div class="section" id="examples">
<h2>例子<a class="headerlink" href="#examples" title="永久链接至标题">¶</a></h2>
<div class="section" id="tcp-echo-server">
<span id="asyncio-example-tcp-echo-server-protocol"></span><h3>TCP回应服务器<a class="headerlink" href="#tcp-echo-server" title="永久链接至标题">¶</a></h3>
<p>Create a TCP echo server using the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a> method, send back
received data, and close the connection:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>


<span class="k">class</span> <span class="nc">EchoServerProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
        <span class="n">peername</span> <span class="o">=</span> <span class="n">transport</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s1">&#39;peername&#39;</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Connection from </span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">peername</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>

    <span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="n">message</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data received: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">message</span><span class="p">))</span>

        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">message</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>

        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Close the client socket&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>

    <span class="n">server</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_server</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">EchoServerProtocol</span><span class="p">(),</span>
        <span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8888</span><span class="p">)</span>

    <span class="k">async</span> <span class="k">with</span> <span class="n">server</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>


<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p>The <a class="reference internal" href="asyncio-stream.html#asyncio-tcp-echo-server-streams"><span class="std std-ref">TCP echo server using streams</span></a>
example uses the high-level <a class="reference internal" href="asyncio-stream.html#asyncio.start_server" title="asyncio.start_server"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.start_server()</span></code></a> function.</p>
</div>
</div>
<div class="section" id="tcp-echo-client">
<span id="asyncio-example-tcp-echo-client-protocol"></span><h3>TCP回应客户端<a class="headerlink" href="#tcp-echo-client" title="永久链接至标题">¶</a></h3>
<p>A TCP echo client using the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> method, sends
data, and waits until the connection is closed:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>


<span class="k">class</span> <span class="nc">EchoClientProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>

    <span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
        <span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data sent: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data received: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()))</span>

    <span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;The server closed the connection&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>

    <span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>
    <span class="n">message</span> <span class="o">=</span> <span class="s1">&#39;Hello World!&#39;</span>

    <span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_connection</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">EchoClientProtocol</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">),</span>
        <span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8888</span><span class="p">)</span>

    <span class="c1"># Wait until the protocol signals that the connection</span>
    <span class="c1"># is lost and close the transport.</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">on_con_lost</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>


<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p>The <a class="reference internal" href="asyncio-stream.html#asyncio-tcp-echo-client-streams"><span class="std std-ref">TCP echo client using streams</span></a>
example uses the high-level <a class="reference internal" href="asyncio-stream.html#asyncio.open_connection" title="asyncio.open_connection"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.open_connection()</span></code></a> function.</p>
</div>
</div>
<div class="section" id="udp-echo-server">
<span id="asyncio-udp-echo-server-protocol"></span><h3>UDP回应服务器<a class="headerlink" href="#udp-echo-server" title="永久链接至标题">¶</a></h3>
<p>A UDP echo server, using the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a>
method, sends back received data:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>


<span class="k">class</span> <span class="nc">EchoServerProtocol</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>

    <span class="k">def</span> <span class="nf">datagram_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
        <span class="n">message</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Received </span><span class="si">%r</span><span class="s1"> from </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">addr</span><span class="p">))</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send </span><span class="si">%r</span><span class="s1"> to </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">addr</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Starting UDP server&quot;</span><span class="p">)</span>

    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>

    <span class="c1"># One protocol instance will be created to serve all</span>
    <span class="c1"># client requests.</span>
    <span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_datagram_endpoint</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">EchoServerProtocol</span><span class="p">(),</span>
        <span class="n">local_addr</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">9999</span><span class="p">))</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3600</span><span class="p">)</span>  <span class="c1"># Serve for 1 hour.</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>


<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="section" id="udp-echo-client">
<span id="asyncio-udp-echo-client-protocol"></span><h3>UDP回应客户端<a class="headerlink" href="#udp-echo-client" title="永久链接至标题">¶</a></h3>
<p>A UDP echo client, using the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a>
method, sends data and closes the transport when it receives the answer:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>


<span class="k">class</span> <span class="nc">EchoClientProtocol</span><span class="p">:</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send:&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>

    <span class="k">def</span> <span class="nf">datagram_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Received:&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>

        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Close the socket&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">error_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Error received:&#39;</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Connection closed&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>

    <span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>
    <span class="n">message</span> <span class="o">=</span> <span class="s2">&quot;Hello World!&quot;</span>

    <span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_datagram_endpoint</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">EchoClientProtocol</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">),</span>
        <span class="n">remote_addr</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">9999</span><span class="p">))</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">on_con_lost</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>


<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
</div>
<div class="section" id="connecting-existing-sockets">
<span id="asyncio-example-create-connection"></span><h3>链接已存在的套接字<a class="headerlink" href="#connecting-existing-sockets" title="永久链接至标题">¶</a></h3>
<p>Wait until a socket receives data using the
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> method with a protocol:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">socket</span>


<span class="k">class</span> <span class="nc">MyProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>

    <span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>

    <span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Received:&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>

        <span class="c1"># We are done: close the transport;</span>
        <span class="c1"># connection_lost() will be called automatically.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
        <span class="c1"># The socket has been closed</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>


<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
    <span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>

    <span class="c1"># Create a pair of connected sockets</span>
    <span class="n">rsock</span><span class="p">,</span> <span class="n">wsock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socketpair</span><span class="p">()</span>

    <span class="c1"># Register the socket to wait for data.</span>
    <span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_connection</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">MyProtocol</span><span class="p">(</span><span class="n">on_con_lost</span><span class="p">),</span> <span class="n">sock</span><span class="o">=</span><span class="n">rsock</span><span class="p">)</span>

    <span class="c1"># Simulate the reception of data from the network.</span>
    <span class="n">loop</span><span class="o">.</span><span class="n">call_soon</span><span class="p">(</span><span class="n">wsock</span><span class="o">.</span><span class="n">send</span><span class="p">,</span> <span class="s1">&#39;abc&#39;</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">protocol</span><span class="o">.</span><span class="n">on_con_lost</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">wsock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p>The <a class="reference internal" href="asyncio-eventloop.html#asyncio-example-watch-fd"><span class="std std-ref">watch a file descriptor for read events</span></a> example uses the low-level
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.add_reader" title="asyncio.loop.add_reader"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.add_reader()</span></code></a> method to register an FD.</p>
<p>The <a class="reference internal" href="asyncio-stream.html#asyncio-example-create-connection-streams"><span class="std std-ref">register an open socket to wait for data using streams</span></a> example uses high-level streams
created by the <a class="reference internal" href="asyncio-stream.html#asyncio.open_connection" title="asyncio.open_connection"><code class="xref py py-func docutils literal notranslate"><span class="pre">open_connection()</span></code></a> function in a coroutine.</p>
</div>
</div>
<div class="section" id="loop-subprocess-exec-and-subprocessprotocol">
<span id="asyncio-example-subprocess-proto"></span><h3>loop.subprocess_exec() and SubprocessProtocol<a class="headerlink" href="#loop-subprocess-exec-and-subprocessprotocol" title="永久链接至标题">¶</a></h3>
<p>An example of a subprocess protocol used to get the output of a
subprocess and to wait for the subprocess exit.</p>
<p>The subprocess is created by th <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a> method:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">sys</span>

<span class="k">class</span> <span class="nc">DateProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">SubprocessProtocol</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exit_future</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exit_future</span> <span class="o">=</span> <span class="n">exit_future</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="nb">bytearray</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">pipe_data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fd</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">process_exited</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exit_future</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">get_date</span><span class="p">():</span>
    <span class="c1"># Get a reference to the event loop as we plan to use</span>
    <span class="c1"># low-level APIs.</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>

    <span class="n">code</span> <span class="o">=</span> <span class="s1">&#39;import datetime; print(datetime.datetime.now())&#39;</span>
    <span class="n">exit_future</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Future</span><span class="p">(</span><span class="n">loop</span><span class="o">=</span><span class="n">loop</span><span class="p">)</span>

    <span class="c1"># Create the subprocess controlled by DateProtocol;</span>
    <span class="c1"># redirect the standard output into a pipe.</span>
    <span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">subprocess_exec</span><span class="p">(</span>
        <span class="k">lambda</span><span class="p">:</span> <span class="n">DateProtocol</span><span class="p">(</span><span class="n">exit_future</span><span class="p">),</span>
        <span class="n">sys</span><span class="o">.</span><span class="n">executable</span><span class="p">,</span> <span class="s1">&#39;-c&#39;</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span>
        <span class="n">stdin</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>

    <span class="c1"># Wait for the subprocess exit using the process_exited()</span>
    <span class="c1"># method of the protocol.</span>
    <span class="k">await</span> <span class="n">exit_future</span>

    <span class="c1"># Close the stdout pipe.</span>
    <span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

    <span class="c1"># Read the output which was collected by the</span>
    <span class="c1"># pipe_data_received() method of the protocol.</span>
    <span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">protocol</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>

<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s2">&quot;win32&quot;</span><span class="p">:</span>
    <span class="n">asyncio</span><span class="o">.</span><span class="n">set_event_loop_policy</span><span class="p">(</span>
        <span class="n">asyncio</span><span class="o">.</span><span class="n">WindowsProactorEventLoopPolicy</span><span class="p">())</span>

<span class="n">date</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">get_date</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Current date: </span><span class="si">{</span><span class="n">date</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>See also the <a class="reference internal" href="asyncio-subprocess.html#asyncio-example-create-subprocess-exec"><span class="std std-ref">same example</span></a>
written using high-level APIs.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#">传输和协议</a><ul>
<li><a class="reference internal" href="#transports">传输</a><ul>
<li><a class="reference internal" href="#transports-hierarchy">传输层级</a></li>
<li><a class="reference internal" href="#base-transport">基础传输</a></li>
<li><a class="reference internal" href="#read-only-transports">只读传输</a></li>
<li><a class="reference internal" href="#write-only-transports">只写传输</a></li>
<li><a class="reference internal" href="#datagram-transports">数据报传输</a></li>
<li><a class="reference internal" href="#subprocess-transports">子进程传输</a></li>
</ul>
</li>
<li><a class="reference internal" href="#protocols">协议</a><ul>
<li><a class="reference internal" href="#base-protocols">基础协议</a></li>
<li><a class="reference internal" href="#base-protocol">基础协议</a></li>
<li><a class="reference internal" href="#streaming-protocols">流协议</a></li>
<li><a class="reference internal" href="#buffered-streaming-protocols">缓冲流协议</a></li>
<li><a class="reference internal" href="#datagram-protocols">数据报协议</a></li>
<li><a class="reference internal" href="#subprocess-protocols">子进程协议</a></li>
</ul>
</li>
<li><a class="reference internal" href="#examples">例子</a><ul>
<li><a class="reference internal" href="#tcp-echo-server">TCP回应服务器</a></li>
<li><a class="reference internal" href="#tcp-echo-client">TCP回应客户端</a></li>
<li><a class="reference internal" href="#udp-echo-server">UDP回应服务器</a></li>
<li><a class="reference internal" href="#udp-echo-client">UDP回应客户端</a></li>
<li><a class="reference internal" href="#connecting-existing-sockets">链接已存在的套接字</a></li>
<li><a class="reference internal" href="#loop-subprocess-exec-and-subprocessprotocol">loop.subprocess_exec() and SubprocessProtocol</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="asyncio-future.html"
                        title="上一章">Futures</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="asyncio-policy.html"
                        title="下一章">策略</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/library/asyncio-protocol.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="asyncio-policy.html" title="策略"
             >下一页</a> |</li>
        <li class="right" >
          <a href="asyncio-future.html" title="Futures"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="asyncio.html" ><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>